package console

type parser struct {
	in           chan *token
	tokens       []*token
	start, width int
	root         node
	current      node
	err          error
}

var eot = &token{end, ""}

func (p *parser) pop() (t *token) {
	return <-p.in
}

func (p *parser) Input() interface{} {
	return &p.in
}

type parserState func(p *parser) parserState


func (p *parser)buildAst() (node, error) {
	for state := parseStart; state != nil; state = state(p) {
	}
	return p.root, p.err
}

func (p*parser)visit(f nodeVisitor) node{
	p.current = p.current.visit(f)
	return p
}

func parseStart(p *parser) parserState {
	switch tok := p.pop(); tok.t {
	case symbol:
		p.current.visit(appendObject(tok))
		return parseMessage
	case number:
		p.current.visit(appendNumber(tok))
		return parseMessage
	case str:
		p.current.visit(appendString(tok))
		return parseMessage
	case end:
		return nil
	}
	return parseError
}

func parseMessage(p *parser) parserState {
	switch tok := p.pop(); tok.t {
	case symbol:
		p.current.visit(unaryMessage(tok))
		
	case operator:
	case keyword:
	}
	return parseError
}

func parseError(p *parser) parserState {
	return nil
}


func appendObject(tok *token)nodeVisitor {
	return func(n node)node{
		if app , ok := n.(appender);ok {
			nn := &reference{tok.value}
			app.appendTo(nn)
			return nn
		}
		return n
	}
}

func appendNumber(tok *token)nodeVisitor {
	return func(n node)node{
		return n
	}
}

func appendString(tok *token)nodeVisitor {
	return func(n node)node{
		return n
	}
}

func unaryMessage(tok *token)nodeVisitor {
	return func(n node)node {
		return n
	}
}